package com.ronri.ams.sample;

/**
 * 文件：ams.java
 * 包名：com.ronri.ams.sample;
 * 说明：
 * 作者：MS During
 * 日期：2017/6/20
 * 历史：
 */

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.utils.DistanceUtil;
import com.cz.nongyetongv5.R;
import com.ronri.mapapi.clusterutil.clustering.Cluster;
import com.ronri.mapapi.clusterutil.clustering.ClusterManager;
import com.ronri.mapapi.location.service.Utils;
import com.ronri.popup.CustomPopupWindows;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;



/****
 * Fragment地图
 */
public class fragmentMap extends Fragment implements BaiduMap.OnMapLoadedCallback {
    private Context mContext = null;
    private MapView mMapView;
    private BaiduMap mBaiduMap;
    private MapStatus ms;
    private ClusterManager<MapItem> mClusterManager = null;
    // 是否创建
    private boolean mIsCreate = false;
//    private LocationService locService;
    private LinkedList<LocationEntity> locationList = new LinkedList<LocationEntity>(); // 存放历史定位结果的链表，最大存放当前结果的前5次定位结果
    private IRemoteMapData OnGetRemoteData = null;
    private CustomPopupWindows popupWindows; // 单个弹框
    private View returnView = null;

    private LocationClient mLocationClient;

    public void setIRemoteMapData(IRemoteMapData callback){
        OnGetRemoteData = callback;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        returnView = inflater.inflate(R.layout.fragment_map, container, false);
        mContext=getActivity();
        Log.i("aaa","fragmentMap");
        mMapView = (MapView) returnView.findViewById(R.id.bmapView);


        //ms = new MapStatus.Builder().target(new LatLng(39.914935, 116.403119)).zoom(5).build();
        mBaiduMap = mMapView.getMap();
        mBaiduMap.setMyLocationEnabled(true);
        mBaiduMap.setOnMapLoadedCallback(this);
        //mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(ms));

//        locService = SystemApplication.locationService;
//        LocationClientOption mOption = locService.getDefaultLocationClientOption();
//        mOption.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
//        mOption.setScanSpan(1);
//        mOption.setCoorType("bd09ll");
//        locService.setLocationOption(mOption);
//        locService.registerListener(listener);
//        locService.start();

        mLocationClient = new LocationClient(mContext);
        mLocationClient.registerLocationListener(listener);

        initLocation();

        mLocationClient.start();
        return returnView;
    }

    private void initLocation(){
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy
        );//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        option.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系
        int span=1000;
        option.setScanSpan(span);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
        option.setOpenGps(true);//可选，默认false,设置是否使用gps
        option.setLocationNotify(true);//可选，默认false，设置是否当gps有效时按照1S1次频率输出GPS结果
        option.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
        option.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
        option.setEnableSimulateGps(false);//可选，默认false，设置是否需要过滤gps仿真结果，默认需要
        mLocationClient.setLocOption(option);
    }

    /***
     * 地图加载信息
     */
    @Override
    public void onMapLoaded() {
        // TODO Auto-generated method stub
        ms = new MapStatus.Builder().zoom(19).build();
        mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(ms));
    }

    /***
     * 定位请求回调函数,这里面会得到定位信息
     *
     * @param bdLocation
     */
    BDLocationListener listener = new BDLocationListener() {
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            int locType = bdLocation.getLocType();
            if (bdLocation != null && (locType == 161 || locType == 66)) {
                Message locMsg = locHander.obtainMessage();
                Bundle locData;
                locData = Algorithm(bdLocation);
                if (locData != null) {
                    locData.putParcelable("loc", bdLocation);
                    locMsg.setData(locData);
                    locHander.sendMessage(locMsg);

                    mLocationClient.stop();
                }
            }
        }

        @Override
        public void onConnectHotSpotMessage(String s, int i) {
        }
    };

    /***
     * 平滑策略代码实现方法，主要通过对新定位和历史定位结果进行速度评分，
     * 来判断新定位结果的抖动幅度，如果超过经验值，则判定为过大抖动，进行平滑处理,若速度过快，
     * 则推测有可能是由于运动速度本身造成的，则不进行低速平滑处理 ╭(●｀∀´●)╯
     *
     * @return Bundle
     */
    private Bundle Algorithm(BDLocation location) {
        Bundle locData = new Bundle();

        double curSpeed = 0;
        if (locationList.isEmpty() || locationList.size() < 2) {
            LocationEntity temp = new LocationEntity();
            temp.location = location;
            temp.time = System.currentTimeMillis();
            locData.putInt("iscalculate", 0);
            locationList.add(temp);
        } else {
            if (locationList.size() > 5)
                locationList.removeFirst();
            double score = 0;
            for (int i = 0; i < locationList.size(); ++i) {
                LatLng lastPoint = new LatLng(locationList.get(i).location.getLatitude(),
                        locationList.get(i).location.getLongitude());
                LatLng curPoint = new LatLng(location.getLatitude(), location.getLongitude());
                double distance = DistanceUtil.getDistance(lastPoint, curPoint);
                curSpeed = distance / (System.currentTimeMillis() - locationList.get(i).time) / 1000;
                score += curSpeed * Utils.EARTH_WEIGHT[i];
            }
            if (score > 0.00000999 && score < 0.00005) { // 经验值,开发者可根据业务自行调整，也可以不使用这种算法
                location.setLongitude(
                        (locationList.get(locationList.size() - 1).location.getLongitude() + location.getLongitude())
                                / 2);
                location.setLatitude(
                        (locationList.get(locationList.size() - 1).location.getLatitude() + location.getLatitude())
                                / 2);
                locData.putInt("iscalculate", 1);
            } else {
                locData.putInt("iscalculate", 0);
            }
            LocationEntity newLocation = new LocationEntity();
            newLocation.location = location;
            newLocation.time = System.currentTimeMillis();
            locationList.add(newLocation);
        }

        return locData;
    }

    /***
     * 接收定位结果消息，并显示在地图上
     */
    private Handler locHander = new Handler() {
        // 接收来自定位的消息
        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            try {
                BDLocation location = msg.getData().getParcelable("loc");
                int iscal = msg.getData().getInt("iscalculate");
                if (location != null) {
                    LatLng point = new LatLng(location.getLatitude(), location.getLongitude());
                    // 构建Marker图标
                    BitmapDescriptor bitmap = null;
                    if (iscal == 0) {
                        bitmap = BitmapDescriptorFactory.fromResource(R.drawable.green); // 非推算结果
                    } else {
                        bitmap = BitmapDescriptorFactory.fromResource(R.drawable.green); // 推算结果
                    }

                    // 构建MarkerOption，用于在地图上添加Marker
                    OverlayOptions option = new MarkerOptions().position(point).icon(bitmap);
                    // 在地图上添加Marker，并显示
                    if (mIsCreate == false) {

                        mBaiduMap.clear();
                        mBaiduMap.addOverlay(option);
                        mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(point));
                        mIsCreate = true;
                    }

                    // 暂停
                    //locService.stop();
                    //locService.unregisterListener(listener);

                    // 已当前点获取周边数据
                    if (OnGetRemoteData != null)
                        OnGetRemoteData.GetRemoteData(point.longitude, point.latitude);
                }
            } catch (Exception e) {
                e.printStackTrace();
                // TODO: handle exception
            }

            super.handleMessage(msg);
        }
    };

    /***
     * 创建聚合点
     */
    public void CreateCluster(List<MapItem> items) {

        if (mClusterManager == null)
            mClusterManager = new ClusterManager<MapItem>(mContext, mBaiduMap);

        // 首先清除
        mClusterManager.clearItems();

        // 添加到点里去
        mClusterManager.addItems(items);

        // 设置地图监听，当地图状态发生改变时，进行点聚合运算
        mBaiduMap.setOnMapStatusChangeListener(mClusterManager);

        // 设置maker点击时的响应
        mBaiduMap.setOnMarkerClickListener(mClusterManager);

        mClusterManager.setOnClusterClickListener(new ClusterManager.OnClusterClickListener<MapItem>() {
            @Override
            public boolean onClusterClick(Cluster<MapItem> cluster) {

                List<Map<String, Object>> listems = new ArrayList<Map<String, Object>>();
                for (MapItem item : cluster.getItems()) {

                    Map<String, Object> listem = new HashMap<String, Object>();
                    listem.put("vtitle", item.mTtitle);
                    listem.put("vhumen", item.mHumen);
                    listem.put("vtelphone", item.mTelphone);
                    listems.add(listem);
                }

                return false;
            }
        });

        // 单击Item返回数据
        mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MapItem>() {
            @Override
            public boolean onClusterItemClick(MapItem item) {

                List<Map<String, Object>> listems = new ArrayList<Map<String, Object>>();

                Map<String, Object> listem = new HashMap<String, Object>();
                listem.put("vtitle", item.mTtitle);
                listem.put("vhumen", item.mHumen);
                listem.put("vtelphone", item.mTelphone);
                listems.add(listem);

                LinearLayout layout = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.enterprise_map_single, null);

                final TextView tvTitle = (TextView) layout.findViewById(R.id.vtitle);
                TextView tvTel = (TextView) layout.findViewById(R.id.vtelphone);
                TextView tvhumen = (TextView) layout.findViewById(R.id.vhumen);
                final Button btSure = (Button) layout.findViewById(R.id.btnSure);

                tvTitle.setText(item.mTtitle);
                tvhumen.setText(item.mHumen);
                tvTel.setText(item.mTelphone);

                btSure.setTag(item);

                btSure.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                        Intent intent = new Intent();
                        Bundle bundle = new Bundle();

                        MapItem ii = (MapItem) btSure.getTag();

                        bundle.putInt("id", ii.mId);
                        bundle.putString("title", ii.mTtitle);
                        bundle.putString("telphone", ii.mTelphone);
                        bundle.putString("humen", ii.mHumen);
                        bundle.putString("regioncode", ii.mRegionCode);

                        intent.putExtras(bundle);

                        popupWindows.dismiss();

                        if (OnGetRemoteData != null){
                            OnGetRemoteData.Seleced(ii);
                        }
                    }
                });

                popupWindows = new CustomPopupWindows(mContext,
                        layout.getRootView());

                //控制键盘是否可以获得焦点
                popupWindows.setFocusable(false);

                // 设置外部可点击
                popupWindows.setOutsideTouchable(true);
                layout.setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {

                        if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                            popupWindows.dismiss();
                        }

                        return true;
                    }
                });

                // 设置弹出窗体显示时的动画，从底部向上弹出
                popupWindows.setAnimationStyle(R.style.take_photo_anim);
                popupWindows.showAtLocation(returnView.findViewById(R.id.bmapView),
                        Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);

                return false;
            }
        });
    }

    /**
     * 封装定位结果和时间的实体类
     *
     * @author baidu
     */
    class LocationEntity {
        BDLocation location;
        long time;
    }
}